package com.zhang.gulimall.authserver.web;

import com.alibaba.fastjson.JSON;
import com.mysql.cj.util.StringUtils;
import com.zhang.gulimall.authserver.feign.MemberFeign;
import com.zhang.gulimall.authserver.feign.ThirdPartyFeign;
import com.zhang.gulimall.authserver.vo.UserLoginVo;
import com.zhang.gulimall.authserver.vo.UserRegisterVo;
import com.zhang.gulimall.common.to.MemberTo;
import com.zhang.gulimall.common.utils.R;
import com.zhang.gulimall.common.vo.GiteeUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
public class LoginController {

    @Resource
    ThirdPartyFeign thirdPartyFeign;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @Autowired
    MemberFeign memberFeign;

    @GetMapping("login.html")
    public String loginPage(Model model, HttpSession session) {
        return session.getAttribute("loginUser") == null ? "login" : "redirect:http://localhost:8000";
    }

    @GetMapping("reg.html")
    public String registerPage(Model model) {
        return "reg";
    }

    @PostMapping("/login")
    public String login(UserLoginVo user, RedirectAttributes redirectAttributes, HttpSession session) {
        R login = memberFeign.login(user);
        if (login.getCode() != 0) {
            // 登录失败
            Map<String, String> errors = new HashMap<>();
            errors.put("errors", String.valueOf(login.get("msg")));
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://localhost:15000/login.html";
        }
        MemberTo memberTo = JSON.parseObject(JSON.toJSONString(login.get("data")), MemberTo.class);

        GiteeUser giteeUser = new GiteeUser();
        giteeUser.setName(memberTo.getNickname());
        session.setAttribute("loginUser", giteeUser);

        return "redirect:http://localhost:8000";
    }

    @PostMapping("/register")
    public String register(@Valid UserRegisterVo user, BindingResult result, RedirectAttributes redirectAttributes) {
        if (result.hasErrors()) {
            Map<String, String> errors
                    = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            redirectAttributes.addFlashAttribute("errors", errors);
            // 如果校验错误，转发到注册页
            return "redirect:http://localhost:15000/reg.html";
        }
        String s = redisTemplate.opsForValue().get(user.getEmail());
        // 验证码过期,或者redis里没有
        if (StringUtils.isEmptyOrWhitespaceOnly(s)) {
            return errorHandle(redirectAttributes, "code", "验证码不存在");
        }
        // 验证码存在,但是错误
        if (!s.equals(user.getCode())) {
            return errorHandle(redirectAttributes, "code", "验证码错误");
        }
        // 验证码正确,保存用户
        // 删除redis缓存
        redisTemplate.delete(user.getEmail());
        R r = memberFeign.register(user);
        if (r.getCode() == 0) {
            // 保存成功
            return "redirect:http://localhost:15000/login.html";
        } else {
            // 保存失败
            return errorHandle(redirectAttributes, "msg", String.valueOf(r.get("msg")));
        }
    }

    public String errorHandle(RedirectAttributes redirectAttributes, String name, String msg) {
        Map<String, String> errors = new HashMap<>();
        errors.put(name, msg);
        redirectAttributes.addFlashAttribute("errors", errors);
        return "redirect:http://localhost:15000/reg.html";
    }

    @ResponseBody
    @GetMapping("/sendCode")
    public R sendCode(@RequestParam String email) {
        // 先查看redis里是否有数据
        String code = redisTemplate.opsForValue().get(email);

        if (!StringUtils.isEmptyOrWhitespaceOnly(code)) {
//            long l = Long.parseLong(code.split("_")[1]);
//            if (System.currentTimeMillis()-l < 60000) {
//
//            }
            return R.error("验证码已发送");
        } else {
            // 没有数据发送验证码
            code = String.valueOf(new Random().nextInt(10000));
//            code+="_"+System.currentTimeMillis();
            if (thirdPartyFeign.sendCode(email, code)) {
                redisTemplate.opsForValue().set(email, code, 60, TimeUnit.SECONDS);
                return R.ok("验证码发送成功");
            } else {
                return R.error("验证码发送失败");
            }
        }
    }
}
